/*
 * File Name：CWSys.java
 * Copyright：Copyright 2008-2014 CiWong.Inc. All Rights Reserved.
 * Description： CWSys.java
 * Modify By：res-jxliu
 * Modify Date：2014-5-28
 * Modify Type：Add
 */
package com.ciwong.libs.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.view.inputmethod.InputMethodManager;

/**
 * 系统相关的处理类
 * 
 * @author res-jxliu
 * @version ciwong v.1.0 2014-5-28
 * @since ciwong v.1.0
 */
public class CWSys
{
    /**
     * 习网存储根目录
     */
    public static final String CW_ROOT_FILE_NAME = "ciwong";

    /**
     * 隐藏文件夹
     */
    public static final String CW_HIDE_FOLDER = ".hidefolder";

    protected static Context mContext;

    /**
     * 设置上下文，供后面使用<br />
     * 注:此方法必须要在应用开启时或是调用内部方法前调用<br />
     * 否则可能会报空指针异常
     * 
     * @param context
     *            上下文
     */
    public static void setContext(Context context)
    {
        mContext = context;
    }

    /**
     * 
     * 获取上下文
     * 
     * @return mContext
     */
    public static Context getContext()
    {
        return mContext;
    }

    /**
     * 习网根目录
     * 
     * @return 习网根目录
     */
    public static String getCiwongRoot()
    {
        return getCiwongRootFolder().getAbsolutePath();
    }

    /**
     * 习网根目录
     * 
     * @return 习网根目录
     */
    public static File getCiwongRootFolder()
    {
        File root = new File(getSDCardFolder(), CW_ROOT_FILE_NAME);
        if (!root.exists())
        {
            root.mkdirs();
        }
        return root;
    }

    /**
     * SD根目录
     * 
     * @return 习网根目录
     */
    public static File getSDCardFolder()
    {
        File root = null;
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState()))
        {
            root = Environment.getExternalStorageDirectory();
        }
        else
        {
            root = Environment.getDataDirectory();
        }
        return root;
    }

    /**
     * 获取隐藏文件夹
     * 
     * @return 路径
     */
    public static String getCWHideFolder()
    {
        final String path = FileUtils.getCiwongRoot() + File.separator + CW_HIDE_FOLDER;
        File f = new File(path);
        if (!f.exists())
        {
            f.mkdir();
        }
        return path;
    }

    /**
     * 获取ciwong开发的apk
     * 
     * 
     * @return PackageInfo的集合
     */
    public static ArrayList<PackageInfo> getInstall()
    {

        ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
        PackageManager pm = mContext.getPackageManager();
        List<PackageInfo> packages = pm
                .getInstalledPackages(PackageManager.PERMISSION_GRANTED);
        for (PackageInfo info : packages)
        {
            if (info.packageName.startsWith("com.ciwong"))
            {
                list.add(info);
            }
        }
        return list;
    }

    /**
     * 根据包名，判断此应用是否已安装
     * 
     * @param packageName
     *            包名
     * 
     * @return boolean
     */
    public static boolean findInstalled(String packageName)
    {
        if (packageName == null)
        {
            return false;
        }
        boolean flag = false;
        PackageManager pm = mContext.getPackageManager();
        List<PackageInfo> packages = pm
                .getInstalledPackages(PackageManager.PERMISSION_GRANTED);
        for (PackageInfo info : packages)
        {
            if (info.packageName.equals(packageName))
            {
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 检测flash是否安装 true 已安装 false 未安装
     * 
     * 
     * @return boolean
     */
    public static boolean checkFlash()
    {

        PackageManager pm = mContext.getPackageManager();
        List<PackageInfo> infoList = pm
                .getInstalledPackages(PackageManager.GET_SERVICES);
        for (PackageInfo info : infoList)
        {
            if ("com.adobe.flashplayer".equals(info.packageName))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 隐藏键盘
     * 
     * 
     */
    public static void hidKeyBoard()
    {

        try
        {
            InputMethodManager inputMethodManager = (InputMethodManager) mContext
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            if (((Activity) mContext).getCurrentFocus() != null)
            {
                if (((Activity) mContext).getCurrentFocus().getWindowToken() != null)
                {
                    inputMethodManager.hideSoftInputFromWindow(
                            ((Activity) mContext).getCurrentFocus()
                                    .getWindowToken(),
                            InputMethodManager.HIDE_NOT_ALWAYS);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 服务是否在运行
     * 
     * 
     * @param className
     *            服务name
     * @return boolean
     */
    public static boolean isServiceRunning(String className)
    {
        boolean isRunning = false;
        ActivityManager activityManager = (ActivityManager) mContext
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> serviceList = activityManager
                .getRunningServices(30);
        if (!(serviceList.size() > 0))
        {
            return false;
        }
        for (int i = 0; i < serviceList.size(); i++)
        {
            if (serviceList.get(i).service.getClassName().equals(className))
            {
                isRunning = true;
                break;
            }
        }
        return isRunning;
    }

    /**
     * 安装apk
     * 
     * @param path
     *            apk路径
     * 
     * @return boolean
     */
    public static boolean installApk(String path)
    {

        File file = new File(path);
        if (!file.exists())
        {
            return false;
        }
        if (!path.endsWith(".apk"))
        {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.parse("file://" + path),
                "application/vnd.android.package-archive");
        mContext.startActivity(intent);
        return true;
    }

    /**
     * 
     * 安装apk
     * 
     * @param path
     *            apk路径
     * @param activity
     *            Activity
     * @param req
     *            返回码
     * @return boolean
     */
    public static boolean installApp(String path, Activity activity, int req)
    {
        if (activity == null)
        {
            return false;
        }
        File file = new File(path);

        if (!file.exists())
        {

            return false;
        }
        if (!path.endsWith(".apk"))
        {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.parse("file://" + path),
                "application/vnd.android.package-archive");
        activity.startActivityForResult(intent, req);
        return true;
    }

    /**
     * 卸载apk
     * 
     * @param pkgName
     *            包名
     * 
     * @return boolean
     */
    public static boolean removeApp(String pkgName)
    {
        if (!isApkInstalled(pkgName))
        {
            return false;
        }
        else
        {
            Uri packageURI = Uri.parse("package:" + pkgName);
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,
                    packageURI);
            mContext.startActivity(uninstallIntent);
            return true;
        }

    }

    /**
     * 
     * 根据apk路径，启动此apk
     * 
     * @param packageName
     *            包名
     * @throws NameNotFoundException
     *             当名称的组件由于没有被绑定而无法解析时，抛出此异常。
     * 
     */
    public void openApp(String packageName) throws NameNotFoundException
    {
        PackageInfo pi = mContext.getPackageManager().getPackageInfo(
                packageName, 0);
        PackageManager pm = mContext.getPackageManager();
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(pi.packageName);
        List<ResolveInfo> apps = pm.queryIntentActivities(resolveIntent, 0);

        ResolveInfo ri = apps.iterator().next();
        if (ri != null)
        {
            String className = ri.activityInfo.name;
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            ComponentName cn = new ComponentName(packageName, className);
            intent.setComponent(cn);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }
    }

    /**
     * 判断apk是否安装
     * 
     * 
     * @param pkgName
     *            包名
     * @return boolean
     */
    public static boolean isApkInstalled(String pkgName)
    {
        try
        {
            mContext.getPackageManager().getPackageInfo(pkgName, 0);
            return true;
        }
        catch (NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取SharedPreferences
     * 
     * @param spName
     *            配置文件名称
     * @return SharedPreferences
     */
    public static SharedPreferences getSharedPreferences(String spName)
    {
        SharedPreferences sp;
        if (spName != null)
        {
            sp = mContext.getSharedPreferences(spName, Context.MODE_PRIVATE);
        }
        else
        {
            sp = PreferenceManager.getDefaultSharedPreferences(mContext);
        }
        return sp;
    }

    /**
     * 获取配置文件中指定键值的字符串
     * 
     * @param key
     *            键值
     * @return String
     */
    public static String getSharedString(String key)
    {
        return getSharedPreferences(null).getString(key, null);
    }

    /**
     * 
     * 获取配置文件中指定键值的字符串
     * 
     * @param spName
     *            配置文件的名称
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return String
     */
    public static String getSharedString(String spName, String key,
            String defValue)
    {
        return getSharedPreferences(spName).getString(key, defValue);
    }

    /**
     * 
     * 获取配置文件中指定键值的数字
     * 
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static int getSharedInt(String key, int defValue)
    {
        return getSharedPreferences(null).getInt(key, defValue);
    }

    /**
     * 
     * 获取配置文件中指定键值的数字
     * 
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static long getSharedLong(String key, long defValue)
    {
        return getSharedPreferences(null).getLong(key, defValue);
    }

    /**
     * 
     * 获取配置文件中指定键值的数字
     * 
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static boolean getSharedBoolean(String key, boolean defValue)
    {
        return getSharedPreferences(null).getBoolean(key, defValue);
    }

    /**
     * 
     * 获取配置文件中指定键值的数字
     * 
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static String getSharedString(String key, String defValue)
    {
        return getSharedPreferences(null).getString(key, defValue);
    }

    /**
     * 获取配置文件中指定键值的数字
     * 
     * @param spName
     *            配置文件名
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static int getSharedInt(String spName, String key, int defValue)
    {
        return getSharedPreferences(null).getInt(key, defValue);
    }

    /**
     * 获取配置文件中指定键值的数字
     * 
     * @param spName
     *            配置文件名
     * @param key
     *            键值
     * @param defValue
     *            默认值
     * @return value
     */
    public static long getSharedLong(String spName, String key, int defValue)
    {
        return getSharedPreferences(null).getLong(key, defValue);
    }

    /**
     * 设置shared值
     * 
     * @param key
     *            键值
     * @param value
     *            value值
     */
    public static void setSharedInt(String key, int value)
    {
        Editor editor = getSharedPreferences(null).edit();
        editor.putInt(key, value);
        editor.commit();
    }

    /**
     * 设置shared值
     * 
     * @param key
     *            键值
     * @param value
     *            value值
     */
    public static void setSharedLong(String key, long value)
    {
        Editor editor = getSharedPreferences(null).edit();
        editor.putLong(key, value);
        editor.commit();
    }

    /**
     * 设置shared值
     * 
     * @param key
     *            键值
     * @param value
     *            value值
     */
    public static void setSharedBoolean(String key, boolean value)
    {
        Editor editor = getSharedPreferences(null).edit();
        editor.putBoolean(key, value);
        editor.commit();
    }

    /**
     * 设置shared值
     * 
     * @param key
     *            键值
     * @param value
     *            value值
     */
    public static void setSharedString(String key, String value)
    {
        Editor editor = getSharedPreferences(null).edit();
        editor.putString(key, value);
        editor.commit();
    }

    /**
     * 设置序列化对像
     * 
     * @param key
     *            键值
     * @param value
     *            value值
     * @throws IOException
     *             IO异常
     */
    public static void setSharedSerializable(String key, Serializable value)
            throws IOException
    {
        File f = new File(getDir(), key);
        setSerializableObject(f, value);
    }

    /**
     * 获取序列化对象
     * 
     * @param key
     *            关键字
     * @return 序列化对象
     * @throws IOException
     *             IO异常
     * @throws ClassNotFoundException
     *             找不到此类，抛出异常
     */
    public static Object getSharedSerializable(String key) throws IOException,
            ClassNotFoundException
    {
        File f = new File(getDir(), key);
        return getSerializableObject(f);
    }

    /**
     * 
     * 获取程序缓存文件目录
     * 
     * @return 缓冲文件目录
     */
    public static File getAppCacheFile()
    {
        return new File(getCWHideFolder());
    }
    
    /**
     * 
     * 获取程序自定义文件目录
     * 
     * @return 文件目录
     */
    public static File getDir()
    {
        return mContext.getDir(CW_HIDE_FOLDER, Context.MODE_PRIVATE);
    }

    /**
     * 获取指定文件内的序列化对像
     * 
     * @param objPath
     *            序列化的对象的路径
     * @return Object
     * @throws IOException
     *             IO异常
     * 
     * @throws ClassNotFoundException
     *             找不到此类，抛出异常
     * 
     * 
     */
    public static Object getSerializableObject(String objPath)
            throws IOException, ClassNotFoundException
    {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(
                objPath));
        Object retValue = in.readObject();
        in.close();
        return retValue;
    }

    /**
     * 获取指定文件内的序列化对像
     * 
     * @param objFile
     *            序列化的文件
     * @return Object
     * @throws ClassNotFoundException
     *             找不到此类，抛出异常
     * @throws IOException
     *             IO异常
     * 
     */
    public static Object getSerializableObject(File objFile)
            throws IOException, ClassNotFoundException
    {
        return getSerializableObject(objFile.getAbsolutePath());
    }

    /**
     * 保存序列化文件
     * 
     * @param file
     *            文件
     * @param value
     *            序列化对象
     * @throws IOException
     *             IO异常
     */
    public static void setSerializableObject(File file, Object value)
            throws IOException
    {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
                file));
        out.writeObject(value);
        out.flush();
        out.close();
    }

    /**
     * 
     * 保存序列化文件
     * 
     * @param path
     *            保存路径
     * @param value
     *            序列化对象
     * @throws IOException
     *             IO异常
     */
    public static void setSerializableObject(String path, Object value)
            throws IOException
    {
        setSerializableObject(new File(path), value);
    }

    /**
     * 
     * 获取应用程序包信息
     * 
     * @return PackageInfo
     */
    public static PackageInfo getSystemPackageInfo()
    {
        try
        {
            return mContext.getPackageManager().getPackageInfo(
                    mContext.getPackageName(), 0);
        }
        catch (NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取版本名称
     * 
     * 
     * @return 版本名称
     */
    public static String getSystemVersion()
    {
        PackageInfo pi = getSystemPackageInfo();
        if (pi != null)
        {
            return pi.versionName;
        }
        return null;
    }

    /**
     * 获取版本号
     * 
     * 
     * @return 版本号
     */
    public static int getSystemVersionCode()
    {
        PackageInfo pi = getSystemPackageInfo();
        if (pi != null)
        {
            return pi.versionCode;
        }
        return -1;
    }
}
